﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
using System.Linq.Expressions;
using SMS.Common.ServiceModel;
using SMS.Common.DataAccess;

namespace SMS.Common.Search
{
    /// <summary>
    /// 使用Linq语法在数据上下文上根据条件搜索结果的搜索提供者。
    /// </summary>
    /// <typeparam name="T">要搜索的实体类型</typeparam>
    public class LinqSearchProvider<T> : ISearchProvider<T> where T:class
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="dataContext">执行搜索的数据上下文</param>
        public LinqSearchProvider(DataContext dataContext)
        {
            this.DataContext = dataContext;
        }

        /// <summary>
        /// 获取数据上下文对象
        /// </summary>
        public DataContext DataContext { get; private set; }

        #region ISearchProvider<T> 成员

        /// <summary>
        /// 搜索并返回结果
        /// </summary>
        /// <param name="condition">搜索条件,必须实现IExpressProvider接口。</param>
        /// <returns>返回搜索结果</returns>
        public SearchResult<T> Search(SearchCondition condition)
        {
            if (!(condition is IExpressProvider))
            {
                throw new InvalidateException("搜索条件必须实现IExpressProvider。");
            }
            
            IExpressProvider ep = condition as IExpressProvider;

            Expression<Func<T, bool>> predicate = ep.GetExpress<T>();
            Table<T> entityTable = this.DataContext.GetTable<T>();
            IQueryable<T> query = null;
            if (predicate != null)
            {
                query = entityTable.Where(predicate);
            }
            else
            {
                query = entityTable;
            }
            if (condition.OrderBy != null) query = query.OrderBy(condition.OrderBy);
            SearchResult<T> sr = new SearchResult<T>();
            sr.TotalCount = query.Count();

            if (sr.TotalCount > 0)
            {
                if (condition.LoadAllRecords == true)//加载全部记录
                {
                    sr.ResultSet = query.ToArray();
                }
                else//分页查询
                {
                    sr.ResultSet = query.Skip(condition.PageSize * condition.CurrentPageIndex)
                        .Take(condition.PageSize)
                        .ToArray();
                }
            }
             return sr;
        }

        #endregion
    }
}
